﻿using System;

namespace CoreEx.Common.Data
{
    /// <summary>
    /// Represents the key of a domain object. 
    /// </summary>
    public class SurrogateKey : IEquatable<SurrogateKey>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SurrogateKey"/> class.
        /// </summary>
        /// <param name="values">The values that makes up this <see cref="SurrogateKey"/>.</param>
        public SurrogateKey(object[] values)
        {
            Values = values;
        }
        
        /// <summary>
        /// Gets the values that makes up this <see cref="SurrogateKey"/>.
        /// </summary>
        public object[] Values { get; private set; }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
        /// </returns>
        public bool Equals(SurrogateKey other)
        {
            if (Values.Length != other.Values.Length)
                return false;
            
            for (int i = 0; i < Values.Length; i++)
            {
                var thisvalue = Values[i];
                var otherValue = other.Values[i];
                if ((thisvalue == null) || (otherValue == null))
                    return false;
                if (!thisvalue.Equals(otherValue))
                    return false;
            }
            return true;
        }

        /// <summary>
        /// Serves as a hash function for a particular type. 
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="SurrogateKey"/>.
        /// </returns>        
        public override int GetHashCode()
        {
            int hashCode = 0;
            foreach (var value in Values)
            {
                hashCode += value.GetHashCode();
            }
            return hashCode;            
        }
    }
}